const puppeteer = require('puppeteer-extra')
const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha')
const config  = require('../config/config');

class helium_login {

    constructor(username,password) {
        this.username = username;
        this.password = password;
        this.page = null;
        this.browser = null;
        this.cookie = null;
    }

    async initPageModule(){
        //使用插件
        puppeteer.use(
            RecaptchaPlugin({
                provider: {
                    id: config.CAPTCHA.ID,
                    token: config.CAPTCHA.API_KEY,
                },
                visualFeedback: true,
            })
        );

        //构建内核对象
        this.browser = await puppeteer.launch({
            headless:true,
            timeout:60000,
            defaultViewport: {
                width: 0,
                height: 0
            },
            args: ['--no-sandbox', '--disable-setuid-sandbox'],
            ignoreDefaultArgs: [
                '--enable-automation',
            ]
        });
        this.page = await this.browser.newPage();
        //伪装真实浏览器
        await this.camouflageBrowser();
    }


    async addCookies(domain){
        let cookie = 'sid=ujfnk1um9oohh0s0j6v2spcre8; _csrf=c35e379aec103016ff9abe53efaf4e5f415a766d4d5ffc8019c06da5f06f5905a%3A2%3A%7Bi%3A0%3Bs%3A5%3A%22_csrf%22%3Bi%3A1%3Bs%3A32%3A%22g6lEb3JakoTZH3SoCJurUJRxw3aArK4r%22%3B%7D; _gcl_au=1.1.1866330163.1621049355; _ga=GA1.3.45014627.1621049356; _gid=GA1.3.906674125.1621049356; _dc_gtm_UA-75738827-2=1; _fbp=fb.1.1621049356413.1625505287; _pin_unauth=dWlkPU5XUTVPR015WVRNdE0yWTNaUzAwTVRreExUa3dZamd0TURCa01ETm1NVE5qTWpWbA; _uetsid=b9a275f0b52d11eb86b40738717184bc; _uetvid=b9a2a5e0b52d11eb98937f38aae61d5f; io=Yr7YvI8mtWJ0KyCHFu8C; AWSALB=wMOWFoTO0DFLmsBefJtlLGRi/FmVKz+le8l8JNTV5dfvTlzWxCmwHEq/z7OZZ2FMAkhD6kYRR5sjQS6QyMf22rDEWm26HCMysyYyvZ7SAYofQL8qu5BqStS4dTbQ; AWSALBCORS=wMOWFoTO0DFLmsBefJtlLGRi/FmVKz+le8l8JNTV5dfvTlzWxCmwHEq/z7OZZ2FMAkhD6kYRR5sjQS6QyMf22rDEWm26HCMysyYyvZ7SAYofQL8qu5BqStS4dTbQ; _gat_UA-75738827-2=1';
        let cookies = cookie.split(';').map(
            pair => {
                let name = pair.trim().slice(0, pair.trim().indexOf('='));
                let value = pair.trim().slice(pair.trim().indexOf('=') + 1);
                return {name, value, domain}
            });
        // console.log(`Cookies => ${JSON.stringify(cookies)}`);
        await Promise.all(cookies.map(pair => {
            return this.page.setCookie(pair)
        }))
    }

    async crackRobot(){
        //开始识别google 机器人
        await this.page.solveRecaptchas();
    }

    async camouflageBrowser(){
        this.page.setRequestInterception(true);
        //设置不加载图片
        // this.page.on('request',async (request) => {
        //     // 如果文件类型为image,则中断加载
        //     if (request.resourceType() === 'image') {
        //         request.abort();
        //         return;
        //     }
        //     // 正常加载其他类型的文件
        //     request.continue();
        // });
        await this.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36');

        //删掉webdriver属性 以免被检测出为无头浏览器
        await this.page.evaluateOnNewDocument(() => {
            const newProto = navigator.__proto__;
            delete newProto.webdriver;
            navigator.__proto__ = newProto;
        });

        //无头浏览器模式下,全局对象下的chrome对象是没有 runtime属性的
        await this.page.evaluateOnNewDocument(() => {
            window.navigator.chrome = {
                runtime: {}
            };
        });
    }


    /**
     * 打开登录页
     * @returns {Promise<void>}
     */
    async openLoginPage(){
        let loginUrl = 'https://members.helium10.com/user/signin';
        try {
            // await this.addCookies('members.helium10.com');
            await this.page.goto(loginUrl,{timeout: 0,waitUntil: ['domcontentloaded']});
            // await this.page.screenshot({ path: "./login.png" });
        } catch (e) {
            throw new Error(`打开页面超时...`);
        }
        console.log(`打开页面成功`)
    }

    /**
     * 输入账号密码
     * @returns {Promise<void>}
     */
    async doLogin(){
        while (true){
            try {
                await this.inputAccountInfo();
                await this.page.waitFor("#loginform-recaptcha-recaptcha-login-form", { timeout: 5000 });
                console.log(`[helium] 开始破解机器人验证...`);
                //识别验证码
                await this.crackRobot();
                break;
            } catch (e) {
                console.log(`[helium] 未出现验证码 自动重试`);
                await this.openLoginPage();
            }
        }
        return (await this.submit());
    }

    async submit(){
        console.log(`[helium] 破解成功 开始登陆...`);
        //点击登录按钮
        // await this.page.click('#login-form > button');
        // await this.page.waitForSelector('#sortable',{timeout:60000});
        // await this.page.waitFor(10000);
        // await this.page.screenshot({ path: "./screenshot.png" });
        // await this.page.waitForNavigation();


        await Promise.all([
            await this.page.click('#login-form > button'),
            await this.page.screenshot({ path: "./screenshot.png" }),
            await this.page.waitForNavigation()
        ]);

        console.log(`[helium] 登录成功`);
        let cks = await this.page.cookies();

        let cookiesStr = cks.map(cookie => `${cookie.name}=${cookie.value}`).join(";");
        cookiesStr = cookiesStr.replace(/\ +/g,"");
        cookiesStr = cookiesStr.replace(/[\r\n]/g,"");

        return cookiesStr;
    }

    async inputAccountInfo(){
        await this.page.type('#loginform-email',this.username);
        await this.page.type('#loginform-password',this.password);
        await this.page.click('#login-form > button');
        console.log(`[helium] 账户密码输入完毕 userName:${this.username} password:${this.password}`);
    }

    async checkRobotDocument(){
        let doc = await this.page.$('#loginform-recaptcha-recaptcha-login-form');
        console.log(`Doc:${doc}`);
        if (doc) {
            const text = await this.page.evaluate(element => element.textContent, doc);
            console.log('doc==='+text.trim());
        }
    }

    async do(){
        //初始化模型对象
        return new Promise(async (resolve, reject) => {
            if(1 === 1){
                reject();
                return;
            }
            await this.initPageModule();
            //打开登录页
            await this.openLoginPage().then(async () => {
                //登录
                await this.doLogin().then((ck) => {
                    resolve(ck);
                }).catch((e) => {
                    console.log(`[helium] => 失败 e:${e.message}`)
                    reject()
                }).finally(async () => {
                    console.log(`[helium] => 关闭浏览器`);
                    // await this.closeBrowser();
                });

            }).catch(async (error) => {
                console.log(`[helium] => ${error.message}`);
                await this.closeBrowser();
                reject()
            });

        })
    }

    async closeBrowser(){
        let pages = await this.browser.pages();
        await Promise.all(pages.map(page =>page.close()));
        await this.browser.close();
    }
}

module.exports = helium_login;
